#pragma once
#include <sys/epoll.h>
#include <stdlib.h>
#include "Log.hpp"
#include "Comm.hpp"

static const int gsize = 128;

using namespace log_ns;

class Epoller
{
public:
    Epoller()
    {
        _epfd = ::epoll_create(gsize);
        if (_epfd < 0)
        {
            LOG(FATAL, "epoll creat error!\n");
            exit(EPOLL_CREAT_ERROR);
        }
        LOG(INFO, "epoll creat success,epfd: %d\n", _epfd);
    }
    std::string EventToString(uint32_t events)
    {
        std::string eventstr;
        if (events & EPOLLIN)
        {
            eventstr = "EPOLLIN";
        }
        if (events & EPOLLOUT)
        {
            eventstr += "|EPOLLIN";
        }
        if (events & EPOLLET)
        {
            eventstr += "|EPOLLET";
        }
        return eventstr;
    }
    bool AddEvents(int fd, uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        int n = ::epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &ev);
        if (n < 0)
        {
            LOG(INFO, "add events fd: %d events: %s error\n", fd, EventToString(events).c_str());
            exit(EPOLL_ADD_ERROR);
        }
        LOG(INFO, "add events success,fd: %d events: %s\n", fd, EventToString(events).c_str());
        return true;
    }
    int Wait(struct epoll_event revs[],int num,int timeout)
    {
        return ::epoll_wait(_epfd,revs,num,timeout);
    }
    bool ModEvents(int fd,uint32_t events)
    {
        struct  epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        int n = epoll_ctl(fd,EPOLL_CTL_MOD,fd,&ev);
        if(n < 0)
        {
            LOG(ERROR,"epoll_ctl add %d events if %s faild\n",fd,EventToString(events).c_str());
            return false;
        }
        LOG(INFO,"epoll_ctl add %d events if %s success\n",fd,EventToString(events).c_str());
        return true;
    }

    void DelEvent(int fd)
    {
        epoll_ctl(_epfd,EPOLL_CTL_DEL,fd,nullptr);
    }

    ~Epoller()
    {
    }

private:
    int _epfd;
};